package com.docker.login;

import com.docker.core.constant.ConfigConstant;
import com.docker.core.constant.MainConstant;
import com.docker.core.mvc.service.BaseService;
import com.docker.sys.app.AppBean;
import com.docker.sys.role.roleMenu.RoleMenuService;
import com.docker.sys.role.rolePerm.RolePermService;
import com.docker.sys.user.UserBean;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.activerecord.tx.TxConfig;
import kit.docker.math.RandomKit;
import kit.docker.sms.SMSKit;

import java.util.List;

/**
 * @Author ldl
 * @Create 2020/10/09 009 16:55
 */
public class LoginService extends BaseService {

    @Inject
    private LoginDao loginDao;

    @Inject
    private RoleMenuService roleMenuService;

    @Inject
    private RolePermService rolePermService;

    @Before(Tx.class)
    @TxConfig(MainConstant.DB_DOCKER)
    public boolean sms(String appId, String account) {
        // 1.获取应用授权
        checkApp(appId);

        // 2.校验用户账户
        if (!loginDao.exist(account)) {
            throwError("账号不存在,请联系管理员");
        }

        // 3.校验验证码是否仍处于有效期
        if (LoginRedis.existSmsCode(appId, account)) {
            long secs = LoginRedis.ttlSmsCode(appId, account);
            long mint = secs / 60;
            if (mint < 1) {
                throwError("请" + secs + "秒后再次获取");
            }
            throwError("请" + mint + "分钟后再次获取");
        }

        // 4.发送短信验证码
        if (PropKit.getBoolean(ConfigConstant.SYS_DEV_MODEL)) {
            //开发模式
            LoginRedis.initSmsCode(appId, account, "000000", 36000);
            return true;
        }
        String smsCode = RandomKit.getAuthCodeNumber(6);
        int time = PropKit.getInt("user.login.smscode.age", 600);
        LoginRedis.initSmsCode(appId, account, smsCode, time);
        SMSKit.send(account, "您登陆系统的验证码为" + smsCode + ",有效期为" + (time / 60) + "分钟，请尽快使用登陆！");
        return true;
    }

    private AppBean checkApp(String appId) {
        AppBean app = getApp(appId);
        if (!"1".equals(app.getUser_token())) {
            throwError("该应用不支持用户登陆使用");
        }
        return app;
    }

    @Before(Tx.class)
    @TxConfig(MainConstant.DB_DOCKER)
    public List<Record> login(String appId, String account, String appVersion, String smsCode, String requestIP) {
        // 1.获取应用授权
        AppBean app = checkApp(appId);

        // 2.校验验证码
        if (!LoginRedis.valiSmsCode(appId, account, smsCode)) {
            throwError("验证码错误");
        }

        // 3.获取用户列表
        List<Record> insides = loginDao.inside(account);
        if (insides.isEmpty()) {
            throwError("账号不存在,请联系管理员");
        }
        for (Record inside : insides) {
            inside.set("app_id", appId);
            inside.set("token", getUUID32());
            inside.remove("password");
        }

        // 5.初始化登录缓存
        LoginRedis.initUserLoginSession(app, insides);

        // 6.剔除关键信息
        clearColumns(insides);

        // 7.登录成功后删除手机验证码
        LoginRedis.delSmsCode(appId, account);
        return insides;
    }

    private void clearColumns(List<Record> userList) {
        for (Record user : userList) {
            user.keep("token", "role_name");
        }
    }

    public Record info(String appId, String token) {
        UserBean userBean = getUser(appId, token);
        Record result = new Record();
        result.set("token", userBean.getToken());
        result.set("user_name", userBean.getUser_name());
        result.set("user_sex", userBean.getUser_sex());
        result.set("role_name", userBean.getRole_name());
        result.set("last_login_ip", userBean.getLast_login_ip());
        result.set("last_login_time", userBean.getLast_login_time());
        return result;
    }

    public boolean logout(String appId, String token) {
        LoginRedis.delUserLoginSession(appId, token);
        return true;
    }

    public Record auth(String appId, String token) {
        UserBean user = getUser(appId, token);
        Record result = new Record();
        result.set("permission", rolePermService.userPerm(appId, isSuperAdmin(user), user.getRole_id()));
        result.set("menu", roleMenuService.tree(appId, isSuperAdmin(user), user.getRole_id()));
        return result;
    }

}
